﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using Contact.DAL.Models.User;
using Contact.DAL.Models.Worktime;
using ContactMvc4TB.Helpers.HelperClasses;
using EFDataModel;
using GlobalResources;

namespace ContactMvc4TB.Models.Worktime
{
    /// <summary>
    /// Model für die Arbeitszeiteinstellungen zum Anlegen und Bearbeiten.
    /// </summary>
    public class EditWorktimeSettingsModel
    {
        #region Private no Modeldata Properties
        /// <summary>
        /// Der Aktuelle CurrentController um hier auch Messages ausgeben zu können.
        /// </summary>
        public Controller CurrentController { get; set; }
        #endregion

        #region Modeldata
        /// <summary>
        /// Die aktuelle UserId
        /// </summary>
        public long UserId { get; private set; }

        [Required]
        [Display(Name = "Worktime", ResourceType = typeof(WorktimeViews))]
        public double WorkingHours { get; set; }

        [Display(Name = "DefaultStartWorktime", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Time)]
        public DateTime DefaultStartWorkingTime { get; set; }

        [Display(Name = "DefaultEndWorktime", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Time)]
        public DateTime DefaultEndWorkingTime { get; set; }

        [Display(Name = "DefaultStartPause", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Time)]
        public DateTime DefaultStartBreakTime { get; set; }

        [Display(Name = "DefaultEndPause", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Time)]
        public DateTime DefaultEndBreakTime { get; set; }

        [Display(Name = "DefaultDescription", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Text)]
        [StringLength(75)]
        public string DefaultWorktimeDescription { get; set; }

        [Required]
        [Display(Name = "Jobstartdate", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Date)]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd.MM.yyyy}")]
        public DateTime EmploymentStartDate { get; set; }

        [Display(Name = "Monday", ResourceType = typeof(WorktimeViews))]
        public bool Mon { get; set; }

        [Display(Name = "Tuesday", ResourceType = typeof(WorktimeViews))]
        public bool Tue { get; set; }

        [Display(Name = "Wednesday", ResourceType = typeof(WorktimeViews))]
        public bool Wed { get; set; }

        [Display(Name = "Thursday", ResourceType = typeof(WorktimeViews))]
        public bool Thu { get; set; }

        [Display(Name = "Friday", ResourceType = typeof(WorktimeViews))]
        public bool Fri { get; set; }

        [Display(Name = "Saturday", ResourceType = typeof(WorktimeViews))]
        public bool Sat { get; set; }

        [Display(Name = "Sunday", ResourceType = typeof(WorktimeViews))]
        public bool Sun { get; set; }

        /// <summary>
        /// Zuordnung der Freien Tage Pro Jahr.
        /// </summary>
        public ICollection<HolidayDays> HolidayDays { get; set; }
        #endregion

        #region Konstruktor
        public EditWorktimeSettingsModel(Controller controller)
        {
            CurrentController = controller;
        }

        public EditWorktimeSettingsModel()
        {
        }
        #endregion

        #region Public Functions
        /// <summary>
        /// Laden der Modeldaten für die Übergebene UserId
        /// </summary>
        /// <param name="userId">Für diese UserID das passende Worktimesetting aus der DB ins Model laden.</param>
        /// <returns>TRUE->Laden erfolgreich | FALSE->Fehler beim Laden der Daten</returns>
        public void LoadModelData(long userId)
        {
            WorktimeSettingsRepository settingsRepository = new WorktimeSettingsRepository(CurrentHttpContext.GetDataModel());
            EFWorktimeSetting worktime = settingsRepository.LoadWorktimeSetting(userId);
            UserId = userId;

            //Wenn bereits ein Worktime Eintrag gefunden werden kann, dann diesen hier laden
            if (worktime != null)
            {
                DefaultStartBreakTime = worktime.DefaultStartBreakTime;
                DefaultEndBreakTime = worktime.DefaultEndBreakTime;
                DefaultStartWorkingTime = worktime.DefaultStartWorkingTime;
                DefaultEndWorkingTime = worktime.DefaultEndWorkingTime;
                DefaultWorktimeDescription = worktime.DefaultWorktimeDescription;
                EmploymentStartDate = worktime.EmploymentStartDate;

                WorkingHours = worktime.WorkingHours;
                Mon = worktime.WorkingDays.Mon;
                Tue = worktime.WorkingDays.Tue;
                Wed = worktime.WorkingDays.Wed;
                Thu = worktime.WorkingDays.Thu;
                Fri = worktime.WorkingDays.Fri;
                Sat = worktime.WorkingDays.Sat;
                Sun = worktime.WorkingDays.Sun;

                HolidayDays = worktime.HolidayDays;
            }
            else
            {
                //Wenn noch kein Worktime Eintrag gefunden werden kann die Daten nur Initialisieren.
                InitializeModelData();
            }
        }

        /// <summary>
        /// Speichern der übergebenen Modeldaten in der DB für die übergebene UserId
        /// </summary>
        /// <param name="userId">Die UserID zu der ein Setting angelegt/bearbeitet werden soll</param>
        /// <returns>TRUE->Speichern erfolgreich | FALSE->Fehler beim Speichern</returns>
        public bool SaveModelData(long userId, Controller controller)
        {
            UserId = userId;
            CurrentController = controller;
            //Laden des passenden Users aus der DB und nur wenn dieser geladen werden kann, kann auch versucht werden
            //die Settings für Ihn zu ändern bzw. anzupassen.
            UserRepository userRep = new UserRepository(CurrentHttpContext.GetDataModel());
            EFAuthentication user = userRep.GetUser(userId);
            if (user != null)
            {
                WorktimeSettingsRepository worktimeSettingsRep = new WorktimeSettingsRepository(CurrentHttpContext.GetDataModel());
                //Prüfen ob für den User bereits Settings existieren
                if (user.EFWorktimeSetting != null)
                {
                    //Speichern der Settings, da diese bereits existiert haben
                    if (worktimeSettingsRep.SaveWorktimeSetting(SetEFModelData(user.EFWorktimeSetting)))
                    {
                        //Eiene Meldung ausgeben, das die Daten erfolgreich gespeichert werden konnten.
                        CustomMessage.CurrentMessage(CurrentController).AddMessage(SystemMessages.SaveWorktimeSettingsSuccess, MessageTypes.ok);
                        return true;
                    }
                    else
                    {
                        //Eiene Meldung ausgeben, das die Daten erfolgreich gespeichert werden konnten.
                        CustomMessage.CurrentMessage(CurrentController).AddMessage(SystemMessages.SaveWorktimeSettingsError, MessageTypes.error);
                    }
                }
                else
                {
                    //Anlegen des Settings für den übergebenen User.
                    if (worktimeSettingsRep.AddWorktimeSetting(SetEFModelData(new EFWorktimeSetting()), user))
                    {
                        //Eiene Meldung ausgeben, das die Daten erfolgreich angelegt werden konnten.
                        CustomMessage.CurrentMessage(CurrentController).AddMessage(SystemMessages.AddWorktimeSettingsSuccess, MessageTypes.ok);
                        return true;
                    }
                    else
                    {
                        //Eiene Meldung ausgeben, das die Daten erfolgreich gespeichert werden konnten.
                        CustomMessage.CurrentMessage(CurrentController).AddMessage(SystemMessages.AddWorktimeSettingsError, MessageTypes.error);
                    }
                }
            }
            else
            {
                //Eiene Meldung ausgeben, das der User nicht gefunden werden konnte
                CustomMessage.CurrentMessage(CurrentController).AddMessage(SystemMessages.UserNotExistsError, MessageTypes.error);
            }

            return false;
        }
        #endregion

        #region Private Functions
        /// <summary>
        /// Setzten der aktuellen Modeldaten im für das EFWorktimeSetting.
        /// </summary>
        /// <param name="setting">Das EFWorktimeSetting in das die Modeldaten übertragen werden sollen.</param>
        private EFWorktimeSetting SetEFModelData(EFWorktimeSetting setting)
        {
            //Die Properties aus dem Model in unser EF Model übertragen.
            setting.DefaultStartBreakTime = DefaultStartBreakTime;
            setting.DefaultEndBreakTime = DefaultEndBreakTime;
            setting.DefaultStartWorkingTime = DefaultStartWorkingTime;
            setting.DefaultEndWorkingTime = DefaultEndWorkingTime;
            setting.EmploymentStartDate = EmploymentStartDate;
            setting.DefaultWorktimeDescription = DefaultWorktimeDescription;

            if (setting.ID == 0)
            {
                setting.WorkingDaysChangedDate = DateTime.Now;
            }
            else
            {
                //Prüfen ob sich die Arbeitstage geändert haben, wenn sich ein Tag geändert hat, dann das Changed Date setzten.
                if (setting.WorkingDays.Mon != Mon || setting.WorkingDays.Tue != Tue ||
                    setting.WorkingDays.Wed != Wed || setting.WorkingDays.Thu != Thu ||
                    setting.WorkingDays.Fri != Fri || setting.WorkingDays.Sat != Sat ||
                    setting.WorkingDays.Sun != Sun)
                {
                    setting.WorkingDaysChangedDate = DateTime.Now;
                }
            }

            setting.WorkingHours = WorkingHours;
            setting.WorkingDays.Mon = Mon;
            setting.WorkingDays.Tue = Tue;
            setting.WorkingDays.Wed = Wed;
            setting.WorkingDays.Thu = Thu;
            setting.WorkingDays.Fri = Fri;
            setting.WorkingDays.Sat = Sat;
            setting.WorkingDays.Sun = Sun;

            return setting;
        }

        /// <summary>
        /// Initialisieren der Modeldaten, z.B. wenn ein neuer Settingseintrag für einen User angelegt werden soll.
        /// </summary>
        private void InitializeModelData()
        {
            //Standardwerte setzten für die Startarbeitszeiten
            DefaultStartWorkingTime = new DateTime(2000, 01, 01, 7, 0, 0);
            DefaultEndWorkingTime = new DateTime(2000, 01, 01, 16, 0, 0);
            DefaultStartBreakTime = new DateTime(2000, 01, 01, 12, 0, 0);
            DefaultEndBreakTime = new DateTime(2000, 01, 01, 12, 30, 0);
            DefaultWorktimeDescription = "Arbeitszeiteintrag";
            EmploymentStartDate = DateTime.Now;
            WorkingHours = 40;

            Mon = true;
            Tue = true;
            Wed = true;
            Thu = true;
            Fri = true;

            HolidayDays = new List<HolidayDays>();
            HolidayDays.Add(new HolidayDays { Days = 25, Year = DateTime.Now.Year });
        }
        #endregion
    }
}